package com.lxt.service.impl;

import com.lxt.common.PagedGridResult;
import com.lxt.es.pojo.Items;
import com.lxt.service.ItemsESService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @author kevin.lv
 * @date 2023/2/26 14:06
 */
@Service
public class ItemsESServiceImpl implements ItemsESService {

    @Autowired
    private ElasticsearchTemplate esTemplate;


    @Override
    public PagedGridResult searchItems(String keywords, String sort, Integer page, Integer pageSize) {

        String perTag = "<font color='red'>";
        String postTag = "</font>";

        Pageable pageable = PageRequest.of(page, pageSize);


        SortBuilder sortBuilder = null;

        if (sort.equals("c")) {
            sortBuilder = new FieldSortBuilder("sellCounts")
                    .order(SortOrder.DESC);
        } else if (sort.equals("p")) {
            sortBuilder = new FieldSortBuilder("price")
                    .order(SortOrder.ASC);
        } else {
            sortBuilder = new FieldSortBuilder("itemName.keyword")
                    .order(SortOrder.ASC);
        }

        String itemNameFiled = "itemName";

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(QueryBuilders.matchQuery(itemNameFiled, keywords))
                .withHighlightFields(new HighlightBuilder.Field(itemNameFiled)
//                        .preTags(perTag)
//                        .postTags(postTag)
                )
                .withSort(sortBuilder)
                //.withSort(sortAge)
                .withPageable(pageable)
                .build();

        AggregatedPage<Items> pagedItems = esTemplate.queryForPage(searchQuery, Items.class,
                new SearchResultMapper() {
                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {

                        List<Items> itemsListHighLight = new ArrayList<>();

                        SearchHits hits = response.getHits();
                        for (SearchHit h : hits) {
                            HighlightField highlightField = h.getHighlightFields().get(itemNameFiled);
                            String itemName = highlightField.getFragments()[0].toString();

                            String itemId = (String) h.getSourceAsMap().get("itemId");
                            String imgUrl = (String) h.getSourceAsMap().get("imgUrl");
                            Integer price = (Integer) h.getSourceAsMap().get("price");
                            Integer sellCounts = (Integer) h.getSourceAsMap().get("sellCounts");

                            Items items = new Items();
                            items.setItemId(itemId);
                            items.setItemName(itemName);
                            items.setImgUrl(imgUrl);
                            items.setPrice(price);
                            items.setSellCounts(sellCounts);
                            itemsListHighLight.add(items);

                        }

                        return new AggregatedPageImpl<>((List<T>) itemsListHighLight,
                                pageable,
                                //Long.valueOf(String.valueOf(response.getHits().getTotalHits())));
                                response.getHits().totalHits);
                    }
                }
        );

        PagedGridResult gridResult = new PagedGridResult();
        gridResult.setRows(pagedItems.getContent());
        gridResult.setPage(page + 1);
        gridResult.setTotal(pagedItems.getTotalPages());
        gridResult.setRecords(pagedItems.getTotalElements());

        return gridResult;
    }
}
